//管理卡牌类

package model

import (
	"fmt"
	"sort"
)

type CardsData struct {
	Suit  int    //花色1-4方梅红黑,5大小王[var Suit int = Value % 100]
	Point int    //牌点数A-2-3-...-10-J-Q-K-小王14-大王15[var Point int = Value / 100]
	Value int    //(花色*100)+牌点数，方便带花色比较大小[Value/100=整除是花色,Value%100=取模是牌点数]
	Name  string //方面测试用(♠1...♠13)
}

// 构造函数，传入54的牌值
func NewCardsData(index int) *CardsData {
	var cd CardsData
	if index <= 0 {
		return &cd
	}
	cd.Suit = ((index - 1) / 13) + 1
	cd.Point = toCardPointAndValue(index, 0)
	cd.Value = toCardPointAndValue(index, 1)
	return &cd
}

/*
传入牌的序号1-54
为了显示牌(101-113:方块A-K,201-213:梅花A-K,301-313:红桃A-K,401-413:黑桃A-K,514:小王,515:大王)
向上取整math.Ceil(),向下取整math.Floor(),取完整后返回的并不是真正的整数，而是float64 类型，所以如果需要int 类型的话需要手动转换
107/100=1(整除=花色),107%100=7(取模=牌点数)
*/
func toCardPointAndValue(index int, ttype int) int {
	val := 0
	if index <= 0 {
		return val
	}
	switch index {
	case 54:
		val = 15 //大王
		if ttype == 1 {
			val = 515 //大王
		}
	case 53:
		val = 14 //小王
		if ttype == 1 {
			val = 514 //小王
		}
	default:
		if ttype == 1 {
			val = (((index-1)/13)+1)*100 + (((index - 1) % 13) + 1)
		} else {
			val = ((index - 1) % 13) + 1 //牌点数1-15,["1","2","3",,,"10","J","Q","K","小王","大王"]
		}
	}
	return val
}

func (cd *CardsData) CardsA() (ans bool)     { return cd.Point == 1 }                                      // 对A返回true，对所有其他返回false
func (cd *CardsData) Cards10() (ans bool)    { return cd.Point == 10 }                                     // 对10返回true，对所有其他返回false
func (cd *CardsData) CardsJQK() (ans bool)   { return cd.Point == 11 || cd.Point == 12 || cd.Point == 13 } // 对J、Q、K返回true，对所有其他返回false
func (cd *CardsData) CardsJOKER() (ans bool) { return cd.Point == 14 || cd.Point == 15 }                   // 对大小王返回true，对所有其他返回false

func (cd *CardsData) ValueEqual(cd2 *CardsData) bool       { return cd.Value == cd2.Value } // 判断相等
func (cd *CardsData) ValueGreaterThan(cd2 *CardsData) bool { return cd.Value > cd2.Value }  // 判断大于
func (cd *CardsData) ValueLessThan(cd2 *CardsData) bool    { return cd.Value < cd2.Value }  // 判断小于

// 参数2:true=正序小到大,false=倒序大到小[牌点数配花色排序]
func SortByCardsPoint(cards []CardsData, b bool) error {
	sort.Slice(cards, func(i, j int) bool {
		if cards[i].Point == cards[j].Point {
			if b {
				return cards[i].Suit < cards[j].Suit
			} //正序
			return cards[i].Suit > cards[j].Suit //倒序
		}
		if b {
			return cards[i].Point < cards[j].Point
		} //正序
		return cards[i].Point > cards[j].Point //倒序
	})
	return nil
}

/*
拼接牌点数方便显示🃏-♠1...♠13
优化拼接，不使用fmt????????????????
*/
func (cd *CardsData) CardsNameOnebyOne() string {
	//黑桃♠,红桃♥,梅花♣,方块♦,小王🃏,大王🃏
	CardSuit := [6]string{"", "♦", "♣", "♥", "♠", "🃏"}
	CardValue := [7]string{"", "A", "J", "Q", "K", "小王", "大王"}

	name := ""
	switch cd.Point {
	case 1:
		name = fmt.Sprintf("%s%s", CardSuit[cd.Suit], CardValue[1])
	case 11, 12, 13, 14, 15:
		name = fmt.Sprintf("%s%s", CardSuit[cd.Suit], CardValue[cd.Point-9])
	default:
		name = fmt.Sprintf("%s%d", CardSuit[cd.Suit], cd.Point)
	}
	return name
}
